package likou;

import java.util.*;

/**
 * @author: Tangxz
 * @email: 1171702529@qq.com
 * @cate: 2021/11/16 10:30
 */
public class _391 {

    public static void main(String[] args) {
        _391 o = new _391();
        System.out.println(o.isRectangleCover(new int[][]
                {{1,2,4,4},{1,0,4,1},{0,2,1,3},{0,1,3,2},{3,1,4,2},{0,3,1,4},{0,0,1,1}}
        ));
    }
    class Line {
        int bottom;
        int top;

        Line(int bottom, int top) {
            this.bottom = bottom;
            this.top = top;
        }

        Line(Line line) {
            this.bottom = line.bottom;
            this.top = line.top;
        }

        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;
            Line line = (Line) o;
            return bottom == line.bottom &&
                    top == line.top;
        }

        @Override
        public int hashCode() {
            return Objects.hash(bottom, top);
        }
    }

    public boolean isRectangleCover(int[][] rectangles) {
        Map<Integer, List<Line>> mapL = new HashMap<>();
        Map<Integer, List<Line>> mapR = new HashMap<>();
        int start = Integer.MAX_VALUE, end = Integer.MIN_VALUE;
        for (int[] numsa : rectangles) {
            start = Math.min(start, numsa[0]);
            end = Math.max(end, numsa[2]);
            Line nowLine = new Line(numsa[1], numsa[3]);
            if (!mapL.containsKey(numsa[0])) {
                List<Line> list = new ArrayList<>();
                mapL.put(numsa[0], list);
            }
            mapL.get(numsa[0]).add(nowLine);
            if (!mapR.containsKey(numsa[2])) {
                List<Line> list = new ArrayList<>();
                mapR.put(numsa[2], list);
            }
            mapR.get(numsa[2]).add(new Line(nowLine));
        }
        for (Integer key : mapR.keySet()) {
            if (key == end) continue;
            if (!mapL.containsKey(key)) {
                return false;
            }
            Line nowL = getLine(mapL.get(key));
            Line nowR = getLine(mapR.get(key));
            if (nowL == null || nowR == null || !nowL.equals(nowR)) return false;
        }
        Line left =getLine(mapL.get(start));
        Line right =getLine(mapR.get(end));
        return left!=null&&right!=null&&left.equals(right);
    }

    public Line getLine(List<Line> lines) {
        lines.sort((l1, l2) -> l1.bottom == l2.bottom ? l1.top - l2.top : l1.bottom - l2.bottom);
        Line nowL = lines.get(0);
        if (lines.size() > 1) {
            for (int i = 1; i < lines.size(); i++) {
                if (lines.get(i).bottom < nowL.top) {
                    return null;
                }
                nowL.top = Math.max(nowL.top, lines.get(i).top);
            }
        }
        return nowL;
    }
}
